package main

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"
)

func getHttpMethods() []string {
	return []string{
		http.MethodGet,
		http.MethodHead,
		http.MethodPost,
		http.MethodPut,
		http.MethodPatch,
		http.MethodDelete,
		// http.MethodConnect,
		// http.MethodOptions,
		// http.MethodTrace,
	}
}

func checkHttpMethod(method string) error {
	for _, v := range getHttpMethods() {
		if v == method {
			return nil
		}
	}

	return errors.New(fmt.Sprintf("%s is not in %s.", method, fmt.Sprintf("%v", getHttpMethods())))
}

func getHttpClient(keepAlive bool, timeout time.Duration) (client http.Client) {
	transport := http.Transport{
		DisableKeepAlives: func() bool {
			return keepAlive
		}(),
	}
	return http.Client{
		Transport: &transport,
		Timeout:   timeout,
	}

}

func HandleReq(ctx context.Context, client http.Client, reqObj Request) (result interface{}, err error) {
	formValues := url.Values{}
	if len(reqObj.FormData) > 0 {
		for k, v := range reqObj.FormData {
			formValues.Add(k, v)
		}
	}

	reader := strings.NewReader(formValues.Encode())
	if checkErr := checkHttpMethod(reqObj.Method); checkErr != nil {
		err = checkErr
		return
	}
	req, err := http.NewRequest(reqObj.Method, reqObj.Url, reader)
	if err != nil {
		fmt.Printf("new request failed, err:%v\n", err)
		return
	}

	if reqObj.Header != nil {
		for k, v := range reqObj.Header {
			req.Header.Set(k, v)
		}
	} else {
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}

	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return
	}
	result = fmt.Sprintf("response: %s \n", body)
	return
}
